今天我們要來用用看 Django 這個框架拉,我們對 Django 都還不熟,那麼就直接照著教學做做看,看會遇到哪些問題,遇到問題就來解決出問題的人 ! 阿不是,是解決出現的問題~
我參考 安裝 Django | Django Girls Tutorial 中文版教材,但老實說,要看中文的文件或書等等資源的時候,你要有這份文件已經過期的心理準備,你需要花費時間去針對過期文件來 debug,RS 建議能 K 英文官方文件的人就盡量 K,但是當你 K 得很心灰意冷的時候,你也是可以考慮參考中文文件,頂多加上 debug 的時間而已,也順便練練 trouble-shooting 的能力,何嘗不是一種好方法呢 ?
因為我們在架設網站的時候,多多少少會引用不同的套件,套件和套件之間可能會有相互依賴關係,而每個套件會有不同的版本,這就會造成很多很多很多的變因,所以呢! 我們需要虛擬環境,你可以把它想成是 VirtualBox 之類的概念,只是 VirtualBox 裝的是作業系統,而我們是裝不同的版本套件。
$ python -m venv your-env-name
$ your-env-name\Scripts\activate.bat
$ pip install django==3.0.3
可到 django 官網 查詢目前最新的穩定版。
$ python django-env\Scripts\django-admin.py startproject mysite .
在這邊我們是建立 Project,而之後我們可以在這個 Project 底下建立許多個 App,可以是部落格,可以是個人首頁,也可以是電商網站等;一個 App 可以被多個 Project 所使用,也就是說,你在目前的 A 專案寫了一個部落格,可是我還有 B 專案也會用到部落格,就可以直接從 A 專案複製部落格 App 到 B 專案。
(在 django 1.7 已被 deprecated)$ python manage.py syncdb
改用
$ python manage.py makemigrations
$ python manage.py migrate
參考 (2015) Django manage.py Unknown command: 'syncdb'
$ python manage.py runserver
$ python manage.py startapp blog
在 mysite/setting.py 中,找到 INSTALLED_APPS 的 list,在最後加入 blog
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(
default=timezone.now()
)
published_date = models.DateTimeField(
blank=True, null=True
)
# 發布就是加上發布時間,並且存到 db 裡
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
這份 code 來自 Django Girls Tutorial
2020-02-09 更新,新增一個 model 後,需要到
blog/admin.py
去註冊這個 model,這樣才會生效,並且每次更改 model 的內容,都要makemigrations
和migrate
。
from django.contrib import admin
from .models import Post
admin.site.register(Post)
> python manage.py makemigrations
> python manage.py migrate
如果 migrate 後還是不成功的話,可以試試看> python manage.py migrate --run-syncdb
$ python manage.py shell
>>> from blog.models import Post
>>> Post.objects.all()
<QuerySet []>
確認裡面還沒有任何的 Post,沒錯,因為我們才剛創麻~ 如果要新增文章的話,我們還需要知道是 "誰" 寫了這篇文章,那麼就來看看怎麼新增使用者吧。
>>> User.objects.all()
<QuerySet []>
# 目前裡面也是沒有任何使用者 der~
# 我們先新增一筆 RS 的使用者
>>> user = User.objects.create_user(username='RS',
password='topsecret', email='rs@handsome.com')
>>> user.save()
>>> User.objects.all()
<QuerySet [<User: RS>]>
# 再新增一筆空的,等等用來測試刪除使用者的
>>> User.objects.create_user(username='test_user').save()
>>> User.objects.all()
<QuerySet [<User: RS>, <User: test_user>]>
>>> User.objects.get(username='test_user').delete()
(1, {'admin.LogEntry': 0,
'auth.User_groups': 0, 'auth.User_user_permissions': 0,
'blog.Post': 0, 'auth.User': 1})
雖然我們還看不到部落格長什麼樣子,但我們已經能透過 django 框架,寫一篇文章進入到資料庫裡,你可能會覺得:「這樣有什麼了不起?」,RS 跟你說,還真的了不起,在沒有框架的輔助下,我們要新增一筆資料到資料庫裡,是需要寫 SQL 語法的,現在你只需要幾行 python codes !
# 寫一篇 Po 文
>>> Post.objects.create(author=user,
title='Sample title', text='test content')
<Post: Sample title>
# 查看是不是真的有新增成功
>>> Post.objects.all()
<QuerySet [<Post: Sample title>]>
# 也可以抓出不同作者的文章
>>> Post.objects.filter(author=user)
<QuerySet [<Post: Sample title>]>
INSERT INTO Post (username, title, text) VALUES ("RS", "Sample title", "Test content.")
這樣看起來是不是用 Django 比較好理解也比較好寫,而且這行還不包含使用者的詳細資料 (password, email, etc...)
在瀏覽器開起來使用的感覺,跟下指令、寫程式操作的感覺,還是差很多的,所以接下來我們就要想辦法讓它看起來像部落格囉 ! 我們可以利用 Django admin 裡有內建的後台管理系統,來試試看吧。
編輯 blog/admin.py
from django.contrib import admin
from .models import Post
# 將我們寫在 model 裡的 Post
# 註冊到 admin 裡面
admin.site.register(Post)
$ python manage.py runserver
打開瀏覽器,輸入 http://127.0.0.1:8000/admin/
,這時候瀏覽器會自動跳轉到 http://127.0.0.1:8000/admin/login/?next=/admin/
,你就可以看到登入的畫面。
然後輸入我們前面所創立的 RS 使用者帳號密碼,疑,怎麼會不能登入?
原來是因為我們沒有權限,確實我們剛在新增 RS 使用者的時候,只有填入 username, password, email 而已,並沒有指定管理員的身分給它,那該怎麼辦呢?
> python manage.py createsuperuser
System check identified some issues:
WARNINGS:
blog.Post.created_date: (fields.W161) Fixed default value provided.
HINT: It seems you set a fixed date / time / datetime value as default for this field. This may not be what you want. If you want to have the current date as default, use `django.utils.timezone.now`
Username (leave blank to use 'rs'):
# 這個時候就可以填入我們的超級使用者(管理員)的帳號囉
> python manage.py createsuperuser
System check identified some issues:
WARNINGS:
blog.Post.created_date: (fields.W161) Fixed default value provided.
HINT: It seems you set a fixed date / time / datetime value as default for this field. This may not be what you want. If you want to have the current date as default, use `django.utils.timezone.now`
Username (leave blank to use 'rs'): admin
Email address: rs@admin.com # 再填入 email
Password: # 以及密碼
Password (again): # 密碼確認
The password is too similar to the username.
This password is too short. It must contain at least 8 characters.
This password is too common.
Bypass password validation and create user anyway? [y/N]: y # 最後確認同意創立管理員帳號
Superuser created successfully.
登入成功後,就會進到後台的管理畫面,就可以去查看/新增/修改各種資料,像是 使用者資訊、部落格文章 等等。
先點 Users 的 Change 按鈕,看到 RS 的這個帳號在 STAFF STATUS 這個欄位是打叉的,表示這個帳號無法登入後台,那我們就讓它可以 !
點進去 RS 裡面,往下滾動到 Permissions,將 Staff status 和 Superuser status 打勾,最後按 Save。
搭拉,變成綠勾勾了,我們事不宜遲,馬上換成 RS 來登入 XD
壓呼,用 RS 登入成功成功 !
點進去 BLOG App 裡的 Posts 欄位的 Change 按鈕,看到 Sample title 就放心了~
再點進去 Sample title 裡面,看有什麼欄位是可以修改的
今天很簡略地帶大家一起走過 Django 的 HelloWorld,離真正能利用 Django,打造出我們想要的電商網站,還有段距離,大家一起努力,加油 <3
今天的文字比較少,所以比前兩天提早一個小時下班了 XD,要邊學習邊有系統地寫成文章,所需要的時間與精力,是比我原本想像的還要多很多的,我每天從十點開始敲鍵盤、想文章結構、邊做邊收集素材、校稿,到完稿大約是六點半到七點左右了,其實才幾天就有點精神耗弱,真的是太弱了QQ,現在的 RS 真的真的很佩服能每天堅持生稿的鐵人賽的前輩們、專欄作家們,還有廣大的自由工作者們,更不用說在職、已婚且有小孩要照顧的人,下了班還要學習與兼顧文章品質,實在是很需要毅力的任務。
明天我們來想辦法在畫面上,生出一點什麼吧 !
我是 RS,這是我的 不做怎麼知道系列 文章,我們 明天見。
喜歡我的文章嗎? 趕快來看看我都發了什麼文章吧:我的文章目錄
歡迎閱讀我的上一篇: [不做怎麼知道系列之Android開發者的30天後端養成故事 Day3] - 讓熱情燒一會兒 #別間斷很重要 #Python資料結構
歡迎閱讀我的下一篇: [不做怎麼知道系列之Android開發者的30天後端養成故事 Day5] - 當個小畫家 #改變我的首頁 #前後端怎麼結合 #讓Django讀取HTML
把文章囤起來,比賽的時候在發,這樣會比較輕鬆 。 (́◕◞౪◟◕‵)*
感謝分享!
我也開始在想要怎麼去調適了
一天完整的一篇文真的很硬QQ
但既然這系列都已經發出來了
還是持續三十天給他發完
安 又是我 來取暖的
剛剛在 blog/model.py複製下面的code,之後python manage.py makemigrations 出現
"typeerror: init() missing 1 required positional argument: 'on_delete'"
原因好像是定義的問題,原來在 blog/model.py第五行少打on_delete=models.CASCADE
最後成功了,還是RS的資料比較好
paul12999 要加 on_delete=models.CASCADE
是因為 author
這個欄位,要綁定 User
model class,希望 User
跟 author
會連動(關聯),如果某個 User
被刪掉了,那麼原本存在 author
也會一起刪
除了 CASCADE
之外,還有其他的
PROTECT
SET_NULL
SET_DEFAULT
SET()
DO_NOTHING
不過我也是沒有很懂每一項是在幹嘛的,需要用到再來查文件